home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1998 September / Macworld (1998-09).dmg / Shareware World / Info / For Developers / MacZoop 1.8.3 / More Classes / File Classes / ZFile.cpp < prev    next >
Text File  |  1998-07-06  |  22KB  |  876 lines

  1. /*************************************************************************************************
  2. *
  3. *
  4. *            MacZoop - "the framework for the rest of us"         
  5. *
  6. *
  7. *
  8. *            ZFile.cpp    -- a generic file object
  9. *
  10. *
  11. *
  12. *
  13. *
  14. *            © 1996, Graham Cox
  15. *
  16. *
  17. *
  18. *
  19. *************************************************************************************************/
  20.  
  21. #include    "ZFile.h"
  22. #include    "MacZoop.h"
  23. #include    "ProjectSettings.h"
  24.  
  25. #if _CUSTOM_ICON_SUPPORT
  26. #include    "PixMapUtils.h"
  27. #include    "ZGWorld.h"
  28. #include    <icons.h>
  29. #endif
  30.  
  31. #include    <finder.h>
  32. #include    <folders.h>
  33.  
  34. /*-------------------------------***  CONSTRUCTOR  ***----------------------------------*/
  35.  
  36.     
  37.  
  38. ZFile::ZFile( const FSSpec& aSpec )
  39.     : ZComrade()
  40. {
  41.     classID = CLASS_ZFile;
  42.     itsSpec = aSpec;
  43.     
  44.     InitFile();
  45. }
  46.  
  47.  
  48. /*-------------------------------***  CONSTRUCTOR  ***----------------------------------*/
  49.  
  50. ZFile::ZFile( Str255 fName )
  51.     : ZComrade()
  52. {
  53.     short    vRefNum;
  54.     
  55.     classID = CLASS_ZFile;
  56.     FailOSErr( GetVol( NULL, &vRefNum ));
  57.     (void) FSMakeFSSpec( vRefNum, 0, fName, &itsSpec );
  58.     
  59.     InitFile();
  60. }
  61.  
  62.  
  63. ZFile::ZFile()
  64.     : ZComrade()
  65. {
  66.     classID = CLASS_ZFile;
  67.     
  68.     itsSpec.vRefNum = 0;
  69.     itsSpec.parID = 0;
  70.     itsSpec.name[0] = 0;
  71. }    
  72.  
  73.  
  74. /*-------------------------------***  DESTRUCTOR  ***----------------------------------*/
  75.  
  76. ZFile::~ZFile()
  77. {
  78.     Close();
  79.     CloseResFork();
  80. }
  81.  
  82.  
  83. /*---------------------------------***  INITFILE  ***----------------------------------*/
  84. /*
  85.     common construction
  86.  
  87. ---------------------------------------------------------------------------------------*/
  88.  
  89. void    ZFile::InitFile()
  90. {
  91.     refNum = _NOT_OPEN;
  92.     resRefNum = _NOT_OPEN;
  93.     isSafeSave = FALSE;
  94.     itsType = kUnknownType;
  95.     itsCreator = gAppSignature;
  96.     ssFSpec = itsSpec;
  97.     
  98.     // if the file already exists, get the file type
  99.     // from the file. If file not found, its type is not yet defined.
  100.     
  101.     FInfo    finderInfo;
  102.     
  103.     if( FSpGetFInfo( &itsSpec, &finderInfo ) == noErr )
  104.         itsType = finderInfo.fdType;
  105.         
  106.     GetDateTime((unsigned long*) &qd.randSeed );
  107.     GetTempFolderID();
  108. }
  109.  
  110.  
  111. /*------------------------------------***  OPEN  ***-----------------------------------*/
  112. /*
  113. Open the file ready for reading or writing
  114. ---------------------------------------------------------------------------------------*/
  115.  
  116. void    ZFile::Open()
  117. {
  118.     FailOSErr( FSpOpenDF( &itsSpec, fsCurPerm, &refNum ));
  119.     SetMark( 0 );
  120. }
  121.  
  122.  
  123. /*----------------------------------***  OPENSAFE  ***---------------------------------*/
  124. /*
  125. Open the file ready for writing via a safe-save temp file
  126. ---------------------------------------------------------------------------------------*/
  127.  
  128. void    ZFile::OpenSafe()
  129. {
  130.     // the file is to opened for a safe save. This creates a temporary file in the system's
  131.     // temp folder, but with a name built from part of the original plus a random number.
  132.     // The file is set to be invisible in the Finder. When the file is later closed, the
  133.     // catalogue entries will be swapped and the temp file deleted.
  134.         
  135.     long    tfRand;
  136.     Str31    tfName;
  137.     
  138.     ssFSpec = itsSpec;
  139.     
  140.     // if the volume of the target and temp folder differ, do a safe save in the
  141.     // target's location, otherwise in the temp items folder. This is because ExchangeFiles
  142.     // only works on the same volume.
  143.     
  144.     if ( itsSpec.vRefNum == tempFVolID )
  145.         ssFSpec.parID = tempFID;
  146.     
  147.     tfRand = ((unsigned long) Random() << 16L ) + Random();
  148.     
  149.     NumToString( ABS( tfRand ), tfName );
  150.     
  151.     // use up to the first 10 chars of the true name, then append our random characters
  152.     
  153.     ssFSpec.name[0] = MIN( ssFSpec.name[0], 10 );
  154.     ConcatPStrings( ssFSpec.name, tfName );
  155.     
  156.     // create and open the file
  157.     
  158.     FailOSErr( FSpCreate( &ssFSpec, gAppSignature, 'temp', smSystemScript ));
  159.     FailOSErr( FSpOpenDF( &ssFSpec, fsCurPerm, &refNum ));
  160.     SetMark( 0 );
  161.     
  162.     isSafeSave = TRUE;    
  163. }
  164.  
  165.  
  166. /*------------------------------------***  CLOSE  ***----------------------------------*/
  167. /*
  168.     closes the file, if open
  169. ---------------------------------------------------------------------------------------*/
  170.  
  171. void    ZFile::Close()
  172. {
  173.     if (( refNum != _NOT_OPEN ) &&
  174.         ( refNum != 0 ))
  175.         FailOSErr( FSClose( refNum ));
  176.         
  177.     refNum = _NOT_OPEN;
  178.     
  179.     // if we are closing after a safe-save, swap the files and delete the temp file, AND,
  180.     // if the original file doesn't exist, create it before swapping it.
  181.     
  182.     if ( isSafeSave )
  183.     {
  184.         isSafeSave = FALSE;
  185.         
  186.         if (! IsReal())
  187.             Create();
  188.         
  189.         // n.b. finder info not swapped, so get that from the temp file and apply to the
  190.         // real file:
  191.         
  192.         FInfo    fi;
  193.         
  194.         FailOSErr( FSpGetFInfo( &ssFSpec, &fi ));
  195.         FailOSErr( FSpExchangeFiles( &itsSpec, &ssFSpec ));
  196.         FailOSErr( FSpDelete( &ssFSpec ));
  197.         
  198.         fi.fdFlags &= ~fInvisible;
  199.         
  200.         FailOSErr( FSpSetFInfo( &itsSpec, &fi ));
  201.     }
  202. }
  203.  
  204.  
  205. /*-----------------------------------***  CREATE  ***----------------------------------*/
  206. /*
  207. create the file on disk. This does not open it.
  208. ---------------------------------------------------------------------------------------*/
  209.  
  210. void    ZFile::Create()
  211. {
  212.     FailOSErr( FSpCreate( &itsSpec, itsCreator, itsType, smSystemScript ));
  213. }
  214.  
  215.  
  216. /*-----------------------------------***  DISCARD  ***---------------------------------*/
  217. /*
  218. deletes the file after closing it if necessary
  219. ---------------------------------------------------------------------------------------*/
  220.  
  221. void    ZFile::Discard()
  222. {
  223.     if (refNum != _NOT_OPEN )
  224.         Close();
  225.         
  226.     FailOSErr( FSpDelete( &itsSpec ));
  227. }
  228.  
  229.  
  230. /*------------------------------***  OPENRESFORK  ***----------------------------------*/
  231. /*
  232.     opens the files's resource fork
  233.  
  234. ---------------------------------------------------------------------------------------*/
  235.  
  236. void    ZFile::OpenResFork()
  237. {
  238.     if ( resRefNum == _NOT_OPEN )
  239.     {
  240.         if ( isSafeSave )
  241.             resRefNum = FSpOpenResFile( &ssFSpec, fsCurPerm );
  242.         else
  243.             resRefNum = FSpOpenResFile( &itsSpec, fsCurPerm );
  244.         
  245.         FailOSErr( ResError());
  246.         FailOSErr((resRefNum == -1)? fnfErr : noErr );
  247.     }
  248.     
  249.     UseResFile( resRefNum );
  250. }
  251.  
  252.  
  253. /*-----------------------------***  CLOSERESFORK  ***----------------------------------*/
  254. /*
  255. Closes the resource fork, if open
  256. ---------------------------------------------------------------------------------------*/
  257.  
  258. void    ZFile::CloseResFork()
  259. {
  260.     if ( resRefNum != _NOT_OPEN )
  261.     {
  262.         CloseResFile( resRefNum );
  263.         FailOSErr( ResError());
  264.     }
  265.     
  266.     resRefNum = _NOT_OPEN;
  267. }
  268.  
  269.  
  270. /*----------------------------***  CREATERESFORK  ***----------------------------------*/
  271. /*
  272. Creates the resource fork, but does not open it
  273. ---------------------------------------------------------------------------------------*/
  274.  
  275. void    ZFile::CreateResFork()
  276. {
  277.     if ( ! HasResFork())
  278.     {
  279.         if ( isSafeSave )
  280.             FSpCreateResFile( &ssFSpec, gAppSignature, itsType, smSystemScript );
  281.         else
  282.             FSpCreateResFile( &itsSpec, gAppSignature, itsType, smSystemScript );
  283.         
  284.         FailOSErr( ResError());
  285.     }
  286. }
  287.  
  288.  
  289. /*----------------------------------***  READ  ***-------------------------------------*/
  290. /*
  291. Read some data (<howMuch> bytes, from current mark) from the file into a buffer
  292. ---------------------------------------------------------------------------------------*/
  293.  
  294. void    ZFile::Read( Ptr inBuffer, long* howMuch )
  295. {
  296.     FailOSErr( isSafeSave? permErr : noErr );
  297.     FailOSErr( FSRead( refNum, howMuch, inBuffer ));
  298. }
  299.  
  300. /*---------------------------------***  WRITE  ***-------------------------------------*/
  301. /*
  302. Write data from the buffer to the file, <howMuch> bytes written from current mark.
  303. ---------------------------------------------------------------------------------------*/
  304.  
  305. void    ZFile::Write( Ptr outBuffer, long* howMuch )
  306. {
  307.     FailOSErr( FSWrite( refNum, howMuch, outBuffer ));
  308. }
  309.  
  310.  
  311. /*---------------------------------***  READ  ***--------------------------------------*/
  312. /*
  313. Reads the entire file into a Handle. The handle is resized initially to the size of the
  314. file. This technique is unsuitable for large files.
  315. ---------------------------------------------------------------------------------------*/
  316.  
  317. void    ZFile::Read( Handle aHandle )
  318. {
  319.     long    howMuch;
  320.     char    hs;
  321.     
  322.     FailNIL( aHandle );
  323.     FailOSErr( isSafeSave? permErr : noErr );
  324.     
  325.     // the handle is sized to the size of the rest of the data in the file, that is, the
  326.     // length less the current position. Override this for different behaviour.
  327.     
  328.     howMuch = GetLength() - GetMark();
  329.     SetHandleSize( aHandle, howMuch );
  330.     
  331.     FailOSErr( MemError());
  332.     
  333.     hs = HGetState( aHandle );
  334.     HLock( aHandle );
  335.     Read( *aHandle, &howMuch );
  336.     HSetState( aHandle, hs );    
  337. }
  338.  
  339.  
  340. /*---------------------------------***  WRITE  ***-------------------------------------*/
  341. /*
  342. Writes a handle to the file from the current mark.
  343. ---------------------------------------------------------------------------------------*/
  344.  
  345. void    ZFile::Write( Handle aHandle )
  346. {
  347.     long    howMuch;
  348.     char    hs;
  349.  
  350.     FailNIL( aHandle );
  351.     
  352.     howMuch = GetHandleSize( aHandle );
  353.     
  354.     hs = HGetState( aHandle );
  355.     HLock( aHandle );
  356.     Write( *aHandle, &howMuch );
  357.     HSetState( aHandle, hs );
  358.     
  359.     // set the length of the file to the current mark, in case the file was
  360.     // shortened. This is OK even if multiple calls are made to this method.
  361.     
  362.     SetLength( GetMark());    
  363. }
  364.  
  365.  
  366. /*---------------------------------***  SETMARK  ***-----------------------------------*/
  367. /*
  368. move the file's mark to the absolute position <aMark>. Mark is set to 0 on Open.
  369. ---------------------------------------------------------------------------------------*/
  370.  
  371. void    ZFile::SetMark( const long aMark )
  372. {
  373.     FailOSErr( SetFPos( refNum, fsFromStart, aMark ));
  374. }
  375.  
  376. /*--------------------------------***  SETTYPE  ***------------------------------------*/
  377. /*
  378. set the type of the file as used in subsequent Create() calls, or if the file already
  379. exists, this changes the file's type on disk. Use with care, since the content of a file
  380. may be totally invalidated by this call.
  381. ---------------------------------------------------------------------------------------*/
  382.  
  383. void    ZFile::SetType( const OSType aType )
  384. {
  385.     if (aType != itsType)
  386.     {    
  387.         itsType = aType;
  388.         
  389.         if ( IsReal())
  390.         {
  391.             FInfo    fi;
  392.             
  393.             FailOSErr( FSpGetFInfo( &itsSpec, &fi ));
  394.             fi.fdType = itsType;
  395.             FailOSErr( FSpSetFInfo( &itsSpec, &fi ));
  396.         }    
  397.     }
  398. }
  399.  
  400.  
  401. /*-------------------------------***  SETCREATOR  ***----------------------------------*/
  402. /*
  403. set the creator of the file as used in subsequent Create() calls, or if the file already
  404. exists, this changes the file's creator on disk.
  405. ---------------------------------------------------------------------------------------*/
  406.  
  407. void    ZFile::SetCreator( const OSType aCreator )
  408. {
  409.     if ( aCreator != itsCreator )
  410.     {    
  411.         itsCreator = aCreator;
  412.         
  413.         if ( IsReal())
  414.         {
  415.             FInfo    fi;
  416.             
  417.             FailOSErr( FSpGetFInfo( &itsSpec, &fi ));
  418.             fi.fdCreator = itsCreator;
  419.             FailOSErr( FSpSetFInfo( &itsSpec, &fi ));
  420.         }    
  421.     }
  422. }
  423.  
  424.  
  425. /*--------------------------------***  GETMARK  ***--------------=---------------------*/
  426. /*
  427. Get the current position of the file
  428. ---------------------------------------------------------------------------------------*/
  429.  
  430. long    ZFile::GetMark()
  431. {
  432.     long    mark = 0;
  433.     
  434.     FailOSErr( GetFPos( refNum, &mark ));
  435.     
  436.     return mark;
  437. }
  438.  
  439. /*--------------------------------***  GETFSSPEC  ***----------------------------------*/
  440. /*
  441. get the file specification record of the file. You can get the name from this.
  442. ---------------------------------------------------------------------------------------*/
  443.  
  444. void    ZFile::GetFSSpec( FSSpec* aSpec )
  445. {
  446.     *aSpec = itsSpec;
  447. }
  448.  
  449.  
  450. /*-------------------------------***  SETRESFORK  ***----------------------------------*/
  451. /*
  452. sets the resfork of this file to be the current resource file, and returns the one set
  453. originally. This will only work if the res fork exists and is open.
  454. ---------------------------------------------------------------------------------------*/
  455.  
  456. void    ZFile::SetResFork(short* curRes)
  457. {
  458.     *curRes = CurResFile();
  459.     
  460.     if ( resRefNum != _NOT_OPEN )
  461.         UseResFile( resRefNum );
  462. }
  463.  
  464.  
  465. /*-------------------------------***  GETLENGTH  ***-----------------------------------*/
  466. /*
  467. Get the length of the file.
  468. ---------------------------------------------------------------------------------------*/
  469.  
  470. long    ZFile::GetLength()
  471. {
  472.     long    len = 0;
  473.     
  474.     FailOSErr( GetEOF( refNum, &len ));
  475.     
  476.     return len;
  477. }
  478.  
  479.  
  480. /*--------------------------------***  SETLENGTH  ***----------------------------------*/
  481. /*
  482. set the length of the file. You should call this after updating a file in case it got
  483. shorter. Write() with a handle argument does this automatically.
  484. ---------------------------------------------------------------------------------------*/
  485.  
  486. void    ZFile::SetLength( const long aLength )
  487. {
  488.     FailOSErr( SetEOF( refNum, aLength ));
  489. }
  490.  
  491.  
  492. /*--------------------------------***  GETTYPE  ***------------------------------------*/
  493. /*
  494. get the file's type
  495. ---------------------------------------------------------------------------------------*/
  496.  
  497. OSType    ZFile::GetType()
  498. {
  499.     return itsType;
  500. }
  501.  
  502.  
  503. /*--------------------------------***  GETINFO  ***------------------------------------*/
  504. /*
  505. get finder info about the file on disk
  506. ---------------------------------------------------------------------------------------*/
  507.  
  508. void    ZFile::GetInfo( FInfo* fi )
  509. {
  510.     if ( isSafeSave )
  511.         FailOSErr( FSpGetFInfo( &ssFSpec, fi ));
  512.     else
  513.         FailOSErr( FSpGetFInfo( &itsSpec, fi ));
  514. }
  515.  
  516.  
  517. /*--------------------------------***  SETINFO  ***------------------------------------*/
  518. /*
  519. set the finder info about the file on disk
  520. ---------------------------------------------------------------------------------------*/
  521.  
  522. void    ZFile::SetInfo( FInfo* fi )
  523. {
  524.     if ( isSafeSave )
  525.         FailOSErr( FSpSetFInfo( &ssFSpec, fi ));
  526.     else
  527.         FailOSErr( FSpSetFInfo( &itsSpec, fi ));
  528. }
  529.  
  530.  
  531. /*-----------------------------***  HASRESFORK  ***------------------------------------*/
  532. /*
  533. does this file have a resource fork? (n.b. if file not created yet, returns false)
  534. ---------------------------------------------------------------------------------------*/
  535.  
  536. Boolean    ZFile::HasResFork()
  537. {
  538.     Str31            fName;
  539.     CInfoPBRec        pb;
  540.     OSErr            theErr;
  541.     
  542.     if ( isSafeSave )
  543.         CopyPString( ssFSpec.name, fName );
  544.     else
  545.         CopyPString( itsSpec.name, fName );
  546.     
  547.     pb.hFileInfo.ioCompletion = NULL;
  548.     pb.hFileInfo.ioNamePtr = fName;
  549.     pb.hFileInfo.ioVRefNum = isSafeSave? ssFSpec.vRefNum : itsSpec.vRefNum;
  550.     pb.hFileInfo.ioDirID = isSafeSave? ssFSpec.parID : itsSpec.parID;
  551.     pb.hFileInfo.ioFDirIndex = 0;
  552.     
  553.     theErr = PBGetCatInfoSync( &pb );
  554.     
  555.     if (theErr)
  556.         return FALSE;
  557.     else
  558.     {
  559.         // see if any physical bytes are alloted to the resource fork
  560.         
  561.         return( pb.hFileInfo.ioFlRPyLen > 0 );
  562.     }        
  563. }
  564.  
  565.  
  566. /*-----------------------------***  HASDATAFORK  ***-----------------------------------*/
  567. /*
  568. does this file have a data fork? (n.b. if file not created yet, returns false)
  569. ---------------------------------------------------------------------------------------*/
  570.  
  571. Boolean    ZFile::HasDataFork()
  572. {
  573.     Str31            fName;
  574.     CInfoPBRec        pb;
  575.     OSErr            theErr;
  576.     
  577.     if ( isSafeSave )
  578.         CopyPString( ssFSpec.name, fName );
  579.     else
  580.         CopyPString( itsSpec.name, fName );
  581.     
  582.     pb.hFileInfo.ioCompletion = NULL;
  583.     pb.hFileInfo.ioNamePtr = fName;
  584.     pb.hFileInfo.ioVRefNum = isSafeSave? ssFSpec.vRefNum : itsSpec.vRefNum;
  585.     pb.hFileInfo.ioDirID = isSafeSave? ssFSpec.parID : itsSpec.parID;
  586.     pb.hFileInfo.ioFDirIndex = 0;
  587.     
  588.     theErr = PBGetCatInfoSync( &pb );
  589.     
  590.     if (theErr)
  591.         return FALSE;
  592.     else
  593.     {
  594.         // see if any physical bytes are alloted to the data fork
  595.         
  596.         return( pb.hFileInfo.ioFlPyLen > 0 );
  597.     }        
  598. }
  599.  
  600.  
  601. /*--------------------------------***  ISREAL  ***-------------------------------------*/
  602. /*
  603. does this file exist on the physical diskdrive (or network volume)?
  604. ---------------------------------------------------------------------------------------*/
  605.  
  606. Boolean    ZFile::IsReal()
  607. {
  608.     OSErr    theErr;
  609.     FInfo    fi;
  610.     
  611.     theErr = FSpGetFInfo( &itsSpec, &fi );
  612.     return (theErr == noErr);
  613. }
  614.  
  615.  
  616. /*-------------------------------***  ISLOCKED  ***------------------------------------*/
  617. /*
  618. is this file locked?
  619. ---------------------------------------------------------------------------------------*/
  620.  
  621. Boolean    ZFile::IsLocked()
  622. {
  623.     OSErr    theErr;
  624.     FInfo    fi;
  625.     
  626.     theErr = FSpGetFInfo( &itsSpec, &fi );
  627.     return (( theErr == noErr ) &&
  628.             ( fi.fdFlags & 0x1000 ));
  629. }
  630.  
  631.  
  632. /*---------------------------------***  ISOPEN  ***------------------------------------*/
  633. /*
  634. is this file currently open?
  635. ---------------------------------------------------------------------------------------*/
  636.  
  637. Boolean    ZFile::IsOpen()
  638. {
  639.     return ( refNum != _NOT_OPEN );
  640. }
  641.  
  642.  
  643.  
  644. /*-----------------------------***  MAKECUSTOMICON  ***--------------------------------*/
  645. /*
  646. add a custom finder icon to the file, built from the picture, pixmap or GWorld object
  647. passed. This is a one-line solution to this problem, and will do the right thing even
  648. if the resource fork is already open, etc.
  649. ---------------------------------------------------------------------------------------*/
  650.  
  651. void    ZFile::MakeCustomIcon( PicHandle srcImage )
  652. {
  653. #if _CUSTOM_ICON_SUPPORT
  654.  
  655.     FailNILParam( srcImage );
  656.     
  657.     Handle icnSuite = ConstructCustomIconSuite( srcImage );
  658.     
  659.     if ( icnSuite )
  660.     {
  661.         SaveCustomIconSuite( icnSuite );
  662.         
  663.         // dispose of the suite, but not the icon data, since we just added it as a resource,
  664.         // and in any case that routine just NULLED the icon data here.
  665.         
  666.         FailOSErr( DisposeIconSuite( icnSuite, FALSE ));
  667.     }
  668. #endif
  669. }
  670.  
  671.  
  672. /*-----------------------------***  MAKECUSTOMICON  ***--------------------------------*/
  673.  
  674. void    ZFile::MakeCustomIcon( ZGWorld* srcImage )
  675. {
  676. #if _CUSTOM_ICON_SUPPORT
  677.  
  678.     FailNILParam( srcImage );
  679.     
  680.     Rect        r;
  681.     PicHandle    p;
  682.     
  683.     SetRect( &r, 0, 0, 32, 32 );
  684.     FailNIL( p = srcImage->MakePicture( &r ));
  685.     
  686.     try
  687.     {
  688.         MakeCustomIcon( p );
  689.     }
  690.     catch( OSErr err )
  691.     {
  692.         KillPicture( p );
  693.         throw err;
  694.     }
  695.     KillPicture( p );
  696.  
  697. #endif
  698. }
  699.  
  700.  
  701. /*------------------------***  CONSTRUCTCUSTOMICONSUITE  ***---------------------------*/
  702. /*
  703. build an icon suite from the picture data passed
  704. ---------------------------------------------------------------------------------------*/
  705.  
  706. Handle    ZFile::ConstructCustomIconSuite( PicHandle srcPic )
  707. {
  708.     Handle    icnSuite = NULL;
  709.  
  710. #if _CUSTOM_ICON_SUPPORT
  711.  
  712.     Handle    theIcon;
  713.     char    pHState;
  714.     
  715.     pHState = HGetState((Handle) srcPic );
  716.     HNoPurge((Handle) srcPic );
  717.     
  718.     FailOSErr( NewIconSuite( &icnSuite ));
  719.     
  720.     FailNIL( theIcon = MakeIconFromPicture( srcPic, kLarge8BitData ));
  721.     FailOSErr( AddIconToSuite( theIcon, icnSuite, kLarge8BitData ));
  722.     
  723.     FailNIL( theIcon = MakeIconFromPicture( srcPic, kLarge4BitData ));
  724.     FailOSErr( AddIconToSuite( theIcon, icnSuite, kLarge4BitData ));
  725.     
  726.     FailNIL( theIcon = MakeIconFromPicture( srcPic, kLarge1BitMask ));
  727.     FailOSErr( AddIconToSuite( theIcon, icnSuite, kLarge1BitMask ));
  728.  
  729.     FailNIL( theIcon = MakeIconFromPicture( srcPic, kSmall8BitData ));
  730.     FailOSErr( AddIconToSuite( theIcon, icnSuite, kSmall8BitData ));
  731.     
  732.     FailNIL( theIcon = MakeIconFromPicture( srcPic, kSmall4BitData ));
  733.     FailOSErr( AddIconToSuite( theIcon, icnSuite, kSmall4BitData ));
  734.     
  735.     FailNIL( theIcon = MakeIconFromPicture( srcPic, kSmall1BitMask ));
  736.     FailOSErr( AddIconToSuite( theIcon, icnSuite, kSmall1BitMask ));
  737.     
  738.     HSetState((Handle) srcPic, pHState );
  739. #endif
  740.     
  741.     return icnSuite;
  742. }
  743.  
  744.  
  745. /*---------------------------***  SAVECUSTOMICONSUITE  ***-----------------------------*/
  746. /*
  747. save the icons in the suite to the resource fork as finder icons
  748. ---------------------------------------------------------------------------------------*/
  749.  
  750. void    ZFile::SaveCustomIconSuite( Handle icnSuite )
  751. {
  752. #if _CUSTOM_ICON_SUPPORT
  753.  
  754.     if ( icnSuite )
  755.     {
  756.         Handle        iconH, oldH;
  757.         short        id = kCustomIconResource;
  758.         
  759.         CreateResFork();
  760.         OpenResFork();
  761.         
  762.         // remove any existing icons in the file. Normally there won't be any since
  763.         // this is usually done under a safe save.
  764.         
  765.         oldH = Get1Resource( kLarge8BitData, id );
  766.         if ( oldH )
  767.         {
  768.             RemoveResource( oldH );
  769.             DisposeHandle( oldH );
  770.         }
  771.         
  772.         oldH = Get1Resource( kLarge4BitData, id );
  773.         if ( oldH )
  774.         {
  775.             RemoveResource( oldH );
  776.             DisposeHandle( oldH );
  777.         }
  778.         
  779.         oldH = Get1Resource( kLarge1BitMask, id );
  780.         if ( oldH )
  781.         {
  782.             RemoveResource( oldH );
  783.             DisposeHandle( oldH );
  784.         }
  785.         
  786.         oldH = Get1Resource( kSmall8BitData, id );
  787.         if ( oldH )
  788.         {
  789.             RemoveResource( oldH );
  790.             DisposeHandle( oldH );
  791.         }
  792.         
  793.         oldH = Get1Resource( kSmall4BitData, id );
  794.         if ( oldH )
  795.         {
  796.             RemoveResource( oldH );
  797.             DisposeHandle( oldH );
  798.         }
  799.         
  800.         oldH = Get1Resource( kSmall1BitMask, id );
  801.         if ( oldH )
  802.         {
  803.             RemoveResource( oldH );
  804.             DisposeHandle( oldH );
  805.         }
  806.         
  807.         // save each icon in the suite
  808.  
  809.         FailOSErr( GetIconFromSuite( &iconH, icnSuite, kLarge8BitData ));
  810.         AddResource( iconH, kLarge8BitData, id, "\p" );
  811.         FailOSErr( ResError());
  812.         AddIconToSuite( NULL, icnSuite, kLarge8BitData );
  813.         ::WriteResource( iconH );
  814.         ReleaseResource( iconH );
  815.         
  816.         FailOSErr( GetIconFromSuite( &iconH, icnSuite, kLarge4BitData ));
  817.         AddResource( iconH, kLarge4BitData, id, "\p" );
  818.         FailOSErr( ResError());
  819.         AddIconToSuite( NULL, icnSuite, kLarge4BitData );
  820.         ::WriteResource( iconH );
  821.         ReleaseResource( iconH );
  822.         
  823.         FailOSErr( GetIconFromSuite( &iconH, icnSuite, kLarge1BitMask ));
  824.         AddResource( iconH, kLarge1BitMask, id, "\p" );
  825.         FailOSErr( ResError());
  826.         AddIconToSuite( NULL, icnSuite, kLarge1BitMask );
  827.         ::WriteResource( iconH );
  828.         ReleaseResource( iconH );
  829.         
  830.         FailOSErr( GetIconFromSuite( &iconH, icnSuite, kSmall8BitData ));
  831.         AddResource( iconH, kSmall8BitData, id, "\p" );
  832.         FailOSErr( ResError());
  833.         AddIconToSuite( NULL, icnSuite, kSmall8BitData );
  834.         ::WriteResource( iconH );
  835.         ReleaseResource( iconH );
  836.         
  837.         FailOSErr( GetIconFromSuite( &iconH, icnSuite, kSmall4BitData ));
  838.         AddResource( iconH, kSmall4BitData, id, "\p" );
  839.         FailOSErr( ResError());
  840.         AddIconToSuite( NULL, icnSuite, kSmall4BitData );
  841.         ::WriteResource( iconH );
  842.         ReleaseResource( iconH );
  843.         
  844.         FailOSErr( GetIconFromSuite( &iconH, icnSuite, kSmall1BitMask ));
  845.         AddResource( iconH, kSmall1BitMask, id, "\p" );
  846.         FailOSErr( ResError());
  847.         AddIconToSuite( NULL, icnSuite, kSmall1BitMask );
  848.         ::WriteResource( iconH );
  849.         ReleaseResource( iconH );
  850.         
  851.         CloseResFork();
  852.         
  853.         // make sure the "custom icon" bit is set in the finder info
  854.         
  855.         FInfo    fi;
  856.         
  857.         GetInfo( &fi );
  858.         fi.fdFlags |= kHasCustomIcon;
  859.         SetInfo( &fi );
  860.     }
  861.  
  862. #endif
  863.  
  864.  
  865. void    ZFile::GetTempFolderID()
  866. {
  867.     short    fv;
  868.     long    fd;
  869.     
  870.     FailOSErr( FindFolder( kOnSystemDisk, kTemporaryFolderType, kCreateFolder, &fv, &fd ));
  871.     
  872.     tempFID = fd;
  873.     tempFVolID = fv;
  874. }
  875.